package com.cardone.common.template.support;

import freemarker.template.*;
import lombok.*;
import lombok.experimental.*;
import lombok.extern.slf4j.*;
import org.apache.commons.lang3.*;

import java.util.*;

/**
 * FreeMarkerTemplate支持
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Accessors(chain = true)
@Slf4j
public class TemplateFreeMarkerSupport implements TemplateSupport {
    /**
     * freemarker.template.Configuratio
     */
    private Configuration configuration;
    /**
     * 文件名解析格式
     */
    private String filePathFormate = "${filePath}.ftl";
    /**
     * 文件名变量名称
     */
    private String filePathVariableName = "${filePath}";
    /**
     * 显示model
     */
    private Boolean showModel;
    /**
     * 显示解析模板后字符串
     */
    private Boolean showProcessTemplateIntoString;
    /**
     * 显示模板字符串
     */
    private Boolean showTemplateString;

    @Override
    public String processString(final String templateString, final Object model) {
        if (StringUtils.isBlank(templateString)) {
            return null;
        }


        if (BooleanUtils.isTrue(this.showModel)) {
            TemplateFreeMarkerSupport.log.warn(Objects.toString(model));
        }

        if (BooleanUtils.isTrue(this.showTemplateString)) {
            TemplateFreeMarkerSupport.log.warn(templateString);
        }

        final String name = java.util.UUID.randomUUID().toString();

        try (java.io.StringWriter writer = new java.io.StringWriter()) {
            try (java.io.Reader reader = new java.io.StringReader(templateString)) {
                final freemarker.template.Template template = new freemarker.template.Template(name, reader, this.configuration);

                template.process(model, writer);

                String str = writer.toString();

                if (BooleanUtils.isTrue(this.showProcessTemplateIntoString)) {
                    TemplateFreeMarkerSupport.log.warn(str);
                }

                return str;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String process(final String filePath, final boolean isFormat, final Object model) {
        try {
            if (BooleanUtils.isTrue(this.showModel)) {
                TemplateFreeMarkerSupport.log.warn(Objects.toString(model));
            }

            final String newFilePath = this.getNewFilePath(filePath, isFormat);

            final freemarker.template.Template template = this.configuration.getTemplate(newFilePath);

            if (BooleanUtils.isTrue(this.showTemplateString)) {
                TemplateFreeMarkerSupport.log.warn(template.toString());
            }

            String str = org.springframework.ui.freemarker.FreeMarkerTemplateUtils.processTemplateIntoString(template, model);

            if (BooleanUtils.isTrue(this.showProcessTemplateIntoString)) {
                TemplateFreeMarkerSupport.log.warn(str);
            }

            return StringUtils.defaultString(str, org.apache.commons.lang3.StringUtils.EMPTY);
        } catch (freemarker.template.TemplateException | java.io.IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String process(final String filePath, final Object model) {
        return this.process(filePath, true, model);
    }

    /**
     * 获取：新文件路径
     *
     * @param filePath 文件路径
     * @param isFormat 是否格式化文件路径
     * @return 新文件路径
     */
    private String getNewFilePath(final String filePath, final boolean isFormat) {
        if (!isFormat) {
            return filePath;
        }

        return StringUtils.replace(this.filePathFormate, this.filePathVariableName, filePath);
    }
}
